package com.med.service.impl;

import com.hankcs.hanlp.HanLP;
import com.med.common.ResponseDTO;
import com.med.entity.DepartmentDO;
import com.med.entity.DoctorDO;
import com.med.enums.ResponseCode;
import com.med.mapper.DoctorMapper;
import com.med.service.DoctorService;
import com.med.service.ScheduleService;
import com.med.vo.AddDoctorVO;
import com.med.vo.QueryDoctorVO;
import com.med.vo.UpdateDoctorVO;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.common.security.utils.SecurityUtils;
import com.ruoyi.system.api.domain.SysUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @BelongsProject: Internet-based-healthcare
 * @BelongsPackage: com.med.service.impl
 * @Author: 小龚
 * @CreateTime: 2025-08-17 10:45
 * @Description: TODO
 * @Version: 1.0
 */
@Service
public class DoctorServiceImpl implements DoctorService {

    private final DoctorMapper doctorMapper;

    private final RedisService redisService;

    @Autowired
    private ScheduleService scheduleService;

    @Autowired
    public DoctorServiceImpl(DoctorMapper doctorMapper, RedisService redisService) {
        this.doctorMapper = doctorMapper;
        this.redisService = redisService;
    }

    // 获取搜索条件中的所属科室
    @Override
    public ResponseDTO getDepartmentOptions() {
        List<DepartmentDO> list = doctorMapper.getDepartmentOptions();
        List<DepartmentDO> tree = buildTree(list);
        return ResponseDTO.success(tree);
    }

    // 查询医生
    @Override
    public List<DoctorDO> getDoctorList(QueryDoctorVO vo) {
        List<Integer> ids = vo.getDoctorDepartmentId();
        Integer departmentId;
        if (ids == null) {
            departmentId = null;
        } else if (ids.size() == 1) {
            departmentId = ids.get(0);
        } else {
            departmentId = ids.get(1);
        }
        List<DoctorDO> doctorList = doctorMapper.getDoctorList(vo, departmentId);
        return doctorList;
    }

    // 修改医生状态
    @Transactional
    @Override
    public ResponseDTO updateDoctorStatus(Integer doctorId, Integer doctorAdminId) {
        try {
            doctorMapper.updateDoctorStatus(doctorId);

            doctorMapper.updateUserStatus(doctorAdminId);

            return ResponseDTO.success();
        } catch (Exception e) {
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseDTO.error(ResponseCode.ERROR);
        }
    }

    // 删除医生
    @Override
    public ResponseDTO deleteDoctor(Integer doctorId) {
        Integer count = doctorMapper.deleteDoctor(doctorId);
        if (count > 0) {
            return ResponseDTO.success();
        }
        return ResponseDTO.error(ResponseCode.ERROR);
    }


    // 新增医生
    @Transactional
    @Override
    public ResponseDTO addDoctor(AddDoctorVO vo) {
        try {
            SysUser sysUser = new SysUser();
            String nickname = vo.getDoctorName();
            String account = HanLP.convertToPinyinString(nickname, "", true);
            String password = SecurityUtils.encryptPassword(vo.getAdminPassword());
            String phoneNumber = vo.getDoctorPhoneNumber();
            sysUser.setUserName(account);
            sysUser.setNickName(nickname);
            sysUser.setPassword(password);
            sysUser.setPhonenumber(phoneNumber);


            // 新增用户
            System.out.println("准备插入用户: " + sysUser);
            doctorMapper.addUser(sysUser);
            Long userId = sysUser.getUserId();
            System.out.println("用户插入成功，userId=" + userId);

            // 新增医生
            vo.setDoctorAdminId(userId);
            List<Integer> list = vo.getDoctorDepartmentId();
            Integer departmentId = list.get(1);

            System.out.println("准备插入医生: " + vo + ", departmentId=" + departmentId);
            doctorMapper.addDoctor(vo, departmentId);
            System.out.println("医生插入成功");
            scheduleService.checkScheduleForDoctor();


            // 用户分配角色
            System.out.println("准备分配角色给 userId=" + userId);
            doctorMapper.assignRoles(userId);
            System.out.println("分配角色成功");

            return ResponseDTO.success();
        } catch (Exception e) {
            // 触发事务回滚
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return ResponseDTO.error(ResponseCode.ERROR);
        }
    }


    // 修改医生
    @Override
    public ResponseDTO updateDoctor(UpdateDoctorVO vo) {
        List<Integer> ids = vo.getDoctorDepartmentId();
        Integer departmentId;
        if (ids.size() != 2) {
            departmentId = null;
        } else {
            departmentId = ids.get(1);
        }
        Integer count = doctorMapper.updateDoctor(vo, departmentId);
        if (count > 0) {
            return ResponseDTO.success();
        }
        return ResponseDTO.error(ResponseCode.ERROR);
    }

    // 构建树形结构
    private List<DepartmentDO> buildTree(List<DepartmentDO> list) {
        List<DepartmentDO> tree = new ArrayList<>();
        Map<Integer, DepartmentDO> map = new HashMap<>();
        // 将科室映射到ID
        for (DepartmentDO departmentDO : list) {
            map.put(departmentDO.getDepartmentId(), departmentDO);
            departmentDO.setChildren(new ArrayList<>());
        }
        // 2. 构建树形结构
        for (DepartmentDO dept : list) {
            Integer parentId = dept.getDepartmentParentId();
            if (parentId == 0) {
                // 顶级科室直接加入
                tree.add(dept);
            } else {
                // 查找父节点
                DepartmentDO parent = map.get(parentId);
                if (parent != null) {
                    // 父节点存在，加入父节点的children
                    parent.getChildren().add(dept);
                } else {
                    // 父节点不存在，作为顶级节点加入（核心修改）
                    tree.add(dept);
                }
            }
        }
        return tree;
    }

}
